from django.core import serializers
from django.shortcuts import render
from django.views import View
from merchandise.models import Category, Column, Merchandise, MerchandiseOptions, MerchandiseImg
from utils.resFormatUtil import ResFormat
from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator
from elasticsearch import Elasticsearch
from utils.verifyUtil import verifyParam
from django.db.models import Q
import json

es = Elasticsearch([{'host': '127.0.0.1', 'port': 9200}])


# Create your views here.
class CategoryView(View):
    def get(self, request, fun):
        if hasattr(self, fun):
            fun = getattr(self, fun)
            return fun(request)
        else:
            return ResFormat(status='PARAM_ERROR').json_response()

    @method_decorator(cache_page(timeout=60 * 10, cache='hot_cache'))
    def all(self, request):
        """
        返回首页菜单分类数据
        :param request:
        :return:
        """
        # 查询所有的类目数据
        category_list = Category.objects.filter(status=0)
        # 讲models模型对象，序列化（转成json字符串），json.loads()，转为python对象【列表，字典】
        category_json = json.loads(serializers.serialize("json", category_list, ensure_ascii=False))

        # 数据处理
        data = {}
        # 获取每个类目信息
        for category in category_json:
            # 判断是否是顶层类目
            fields = category['fields']
            fields['id'] = category['pk']
            if fields['superior']:
                # 子类目
                if not data.get(fields['superior']):
                    data[fields['superior']] = {}

                if data[fields['superior']].get('son'):
                    data[fields['superior']]['son'].append(fields)
                else:
                    data[fields['superior']]['son'] = [fields]
            else:
                # 顶层类目
                if not data.get(category['pk']):
                    data[category['pk']] = {}
                data[category['pk']]['fields'] = fields

        data = [i for i in list(data.values()) if i.get('fields')]

        return ResFormat(data=data).json_response()

    def update(self, request):
        category_list = Category.objects.filter(status=0)
        category_json = json.loads(serializers.serialize("json", category_list, ensure_ascii=False))
        for category in category_json:
            # 创建索引 index=索引，id文档 body文档内容
            es.index(index='category', id=category['pk'], body=category['fields'])
        return ResFormat(data=category_json).json_response()

    def search(self, request):
        """
        搜索联想-类目
        :param request:
        :return:
        """
        q = request.GET.get('q')

        query = {
            "query": {
                "match": {
                    "name": q
                }
            },
            "highlight": {
                "pre_tags": "<span class='search-key'>",
                "post_tags": "</span>",
                "fields": {
                    "name": {}
                }
            },
            "_source": ["name"]
        }
        data = es.search(index='category', body=query)
        data = [{'highlight': hit['highlight'], "_source": hit['_source']} for hit in data['hits']['hits']]
        return ResFormat(data=data).json_response()


class ColumnMerchandiseNormalView(View):
    def get(self, request):
        """
        获取所有正常栏目的所有商品
        :param request:
        :return:
        """
        # 查询栏目中status为0的所有的数据
        # column_list = Column.objects.filter(status=0)
        column_list = Column.objects.filter(status=0).order_by('priority')
        column_json = json.loads(serializers.serialize("json", column_list, ensure_ascii=False))

        data = [column['fields'] for column in column_json]
        for i in range(len(column_list)):
            # 得到正常的每个栏目，查询该栏目status为0的商品
            merchandise_list = column_list[i].merchandise_set.filter(status=0).order_by('priority')
            merchandise_json = json.loads(serializers.serialize("json", merchandise_list, ensure_ascii=False))

            data[i]['merchandise_list'] = []
            for merchandise in merchandise_json:
                merchandise['fields']['id'] = merchandise['pk']
                data[i]['merchandise_list'].append(merchandise['fields'])

        return ResFormat(data=data).json_response()


class MerchandiseView(View):
    def get(self, request, fun):
        if hasattr(self, fun):
            fun = getattr(self, fun)
            return fun(request)
        else:
            return ResFormat(status='PARAM_ERROR').json_response()

    def search(self, request):
        """
        搜索商品
        :param request:
        :return:
        """
        get = request.GET
        q = get.get('q')
        query = {
            "query": {
                "match": {
                    "title": q
                }
            },
            "_source": ["category"]
        }
        data = es.search(index='yige_shopping', body=query)

        should = [
            {
                "match": {
                    "title": q
                }
            }
        ]
        category_ids = [hit['_source']['category'] for hit in data['hits']['hits']]
        category_list = Category.objects.filter(name=q, status=0).values('id')
        for category in category_list:
            category_ids.append(category['id'])
        category_son_list = Category.objects.filter(superior__in=category_ids, status=0).values('id')
        for category in category_son_list:
            category_ids.append(category['id'])

        for i in category_ids:
            term = {
                "term": {
                    "category": i
                }
            }
            should.append(term)

        query = {
            "query": {
                "bool": {
                    "should": should
                }
            },
            "highlight": {
                "pre_tags": "<span class='search-key'>",
                "post_tags": "</span>",
                "fields": {
                    "title": {}
                }
            },
            "_source": ["title", "subtitle", "cover_img", "priority"]
        }
        data = es.search(index='yige_shopping', body=query)
        data = [{'highlight': hit.get('highlight', None), "_source": hit['_source'], '_id': hit['_id']} for hit in
                data['hits']['hits']]
        return ResFormat(data=data).json_response()

    def delete_by_id(self, request):
        return ResFormat(data='delete_by_id').json_response()

    def update(self, request):
        merchandise_list = Merchandise.objects.filter(status=0)
        merchandise_json = json.loads(serializers.serialize("json", merchandise_list, ensure_ascii=False))
        for merchandise in merchandise_json:
            # 创建索引 index=索引，id文档 body文档内容
            es.index(index='yige_shopping', id=merchandise['pk'], body=merchandise['fields'])
        return ResFormat(data=merchandise_json).json_response()

    @method_decorator(verifyParam('id'))
    def by_category(self, request):
        """
        根据类目id获取该类目及其子类目下面的所有正常状态的商品
        :param request:
        :return:
        """
        get = request.GET
        id = get.get('id')

        # 获取类目id
        category_ids = [category.id for category in Category.objects.filter(Q(id=id) | Q(superior=id))]
        # 获取这些类目的商品数据
        merchandise_list = Merchandise.objects.filter(status=0, category_id__in=category_ids)
        merchandise_json = json.loads(serializers.serialize("json", merchandise_list, ensure_ascii=False))

        data = []
        for merchandise in merchandise_json:
            merchandise['fields']['id'] = merchandise['pk']
            data.append(merchandise['fields'])
        return ResFormat(data=data).json_response()

    @method_decorator(verifyParam('id'))
    def by_id(self, request):
        get = request.GET
        id = get.get('id')

        merchandise = Merchandise.objects.filter(id=id, status=0).values('id', 'title', 'subtitle')[0]
        return ResFormat(data=merchandise).json_response()


class MerchandiseOptionsView(View):
    def get(self, request, fun):
        if hasattr(self, fun):
            fun = getattr(self, fun)
            return fun(request)
        else:
            return ResFormat(status='PARAM_ERROR').json_response()

    @method_decorator(verifyParam('id'))
    def by_merchandise(self, request):
        """
        获取商品选项
        :param request:
        :return:
        """
        get = request.GET
        id = get.get('id')
        merchandise_options = MerchandiseOptions.objects.filter(status=0, merchandise_id=id, merchandise__status=0)
        merchandise_options_json = json.loads(serializers.serialize("json", merchandise_options, ensure_ascii=False))

        data = {}
        for merchandise_option in merchandise_options_json:
            key = merchandise_option['fields']['option_name']
            fields = merchandise_option['fields']
            if not data.get(key, None):
                data[key] = []

            data[key].append({
                'options': fields['options'],
                'price': fields['price'],
                'inventory': fields['inventory'],
                'img': fields['img'],
                'id': merchandise_option['pk']
            })
        data = list(data.items())
        data.sort(key=lambda x: len(x[1]))
        return ResFormat(data=data).json_response()


class MerchandiseImgView(View):
    def get(self, request, fun):
        if hasattr(self, fun):
            fun = getattr(self, fun)
            return fun(request)
        else:
            return ResFormat(status='PARAM_ERROR').json_response()

    @method_decorator(verifyParam('id', 'type'))
    def by_merchandise(self, request):
        """
        获取产品介绍素材图
        :param request:
        :return:
        """
        get = request.GET
        id = get.get('id')
        type = get.get('type')

        merchandise_img = MerchandiseImg.objects.filter(status=0, type=type, merchandise_id=id,
                                                        merchandise__status=0).order_by('priority')
        data = json.loads(serializers.serialize("json", merchandise_img, ensure_ascii=False))
        data = [i['fields'] for i in data]
        return ResFormat(data=data).json_response()
